; if
(str "2 is " (if even? 2) " even " "odd")
(if (true? false) "impossible!")
(if true :truthy :falsey)
(if (Object.) :truthy :falsey)
(if [] :truthy :false)
(if 0 :truthy :falsey)
(if false :truthy :falsey)
(if nil :truthy :falsey)

; if and do
(if (even? 5)
  (do (println "even")
      true)
  (do (println "odd")
      false))

; when
(def x -1)
(when (neg? x)
  (throw (RuntimeException. (str "x must be positive: " x)))
  (x))
(when (neg? x)
  (println "x is a negative value")
  x)

;cond
(let [x 5]
  (cond
    (< x 2) "x is less than 2"
    (< x 10) "x is less than 10"))
(let [x 11]
  (cond
    (< x 2)"x is less than 2"
    (< x 10) "x is less than 10"
    :else "x is greater than or equal to 10"))

; case
(defn foo [x]
  (case x
    5 "x is 5"
    10 "x is 10"
    "x is not support"))
(foo 10)
(foo 11)

; dotimes
(dotimes [i 3]
  (println i))

;doseq
(doseq [n (range 3)]
  (println n))

; doseq with multiple bindings
(doseq [letter [:a :b]
  number (range 3)]
  (println [letter number]))

; for
(for [letter [:a :b]
      number (range 3)]
      [letter number])

; recursion
; loop and recur
(loop [i 0]
  (if (< i 10)
    (recur (inc i))
    i))

; defn and recur
(defn increase [i]
  (if (< i 10)
    (recur (inc i))
    i))
(increase 1)

; try catch
(try
  (/ 2 1)
  (catch ArithmeticException e
  "divide by zero")
  (finally
    (println "cleanup")))

; throwing execptions
(try
  (throw (Exception. "something went wrong"))
  (catch Exception e (.getMessage e)))

; exceptions with clojure data
(try
  (throw (ex-info "There was a problem" {:detail 42}))
  (catch Exception e
    (prn (:detail (ex-data e)))))

;with-open
(let [f (clojure.java.io/writer "/tmp/new")]
  (try
    (.write f "some text")
    (finally
      (.close f))))

; can be wirtten
(with-open [f (clojure.java.io/writer "/tmp/new")]
  (.write f "some text"))
